package SecondeStage.FanShe;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;


public class ReflectionQuestion {
    public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
        // 根据配置文件 re.properties 指定信息,创建Cat对象并调用方法hi

        // 传统方式
        Cat cat =new Cat();
        cat.hi();

        //1. 使用Properties类，可以读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("FengJiDuo\\src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString(); // SecondeStage.FanShe.Cat
        String method = properties.get("method").toString(); // hi()
        System.out.println("classfullpath=" + classfullpath);
        System.out.println("method=" +method);

        //2. 创建对象，传统的方法，行不通。 因为classfullpath是一个字符串
        //new classfulpath();

        //3. 使用反射机制解决
        // (1) 加载类 返回Class类型的对象, 一个类只有一个Class对象
        Class cls =Class.forName(classfullpath);
        // (2) 通过cls 得到你加载的类SecondeStage.FanShe.Cat的对象实例
        Object o = (Cat)cls.newInstance();
        System.out.println(o.getClass());
        // (3) 通过 cls 得到你加载的类SecondeStage.FanShe.Cat的 method "hi"方法对象
        // 即：在反射中，可以把方法视为对象(万物皆对象)
        Method method1= cls.getMethod(method);
        // (4) 通过method1 调用方法: 即通过方法对象来实现调用方法
        method1.invoke(o); // 传统方法: 对象.方法() , 反射机制: 方法.invoke(对象)
    }
}

class Cat{
    private String name="小七";
    public int age=3;
    public void hi(){
        System.out.println("hi~");
    }

    public void cry(){
        System.out.println("cry~");
    }

    public Cat(String name) {
        this.name = name;
    }

    public Cat() {}
}